package taskTracker;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;

import org.j4me.logging.Log;

import taskTracker.util.Serializable;

/**
 * A list that holds tasks
 * @author aseldawy
 *
 */
public class Project extends TaggableObject implements Serializable {
	/**Name of this list*/
	private String name;
	/**Notes about the list*/
	private String notes;
	/**Tasks inside this list*/
	private Vector tasks;
	
	public Project(String name, String notes) {
		this.name = name;
		this.notes = notes;
		this.tasks = new Vector();
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getNotes() {
		return notes;
	}

	public void setNotes(String notes) {
		this.notes = notes;
	}

	public Vector getTasks() {
		return tasks;
	}
	
	public Vector getTrackableTasks() {
		Vector trackableTasks = new Vector();
		for (Enumeration e = this.getTasks().elements(); e.hasMoreElements();) {
			Task task = (Task) e.nextElement();
			if (task.isTrackable())
				trackableTasks.addElement(task);
		}
		return trackableTasks;
	}
	
	/**
	 * Adds a task to this list
	 * @param task
	 */
	public void addTask(Task task) {
		if (task.getParent() != null) {
			task.getParent().removeTask(task);
		}
		this.tasks.addElement(task);
		task.parent = this;
	}

	/**
	 * Removes a task from this list
	 * @param task
	 */
	public void removeTask(Task task) {
		this.tasks.removeElement(task);
		task.parent = null;
		// Remove time entries associated with this task
		task.removeTimeEnries();
	}

	public String toString() {
		return this.getName()+"("+this.getTasks().size()+")";
	}

	public long getTotalTime(){		
		long result = 0;
		
		for(int i = 0; i < tasks.size(); i++){
			Task task = (Task)tasks.elementAt(i);
			
			result += TimeEntries.getInstance().getTotalTimeForTask(task);
		}
		
		return result;
	}
	public Project(DataInputStream dis) {
		try
		{
			super.deserialize(dis);
			name=dis.readUTF();
			notes=dis.readUTF();
			int tasksVectorSize= dis.readInt();
			Vector tasksVector = new Vector(tasksVectorSize);
			Task task;
			for (int i=0;i<tasksVectorSize; i++)
			{
				task = new Task(dis);
				task.parent = this;
				
				tasksVector.addElement(task);
			}
			tasks = tasksVector;
		}
		catch(IOException e)
		{
			System.out.println(e);
		}
	}

	public void serialize(DataOutputStream dos) {
		try
		{
			super.serialize(dos);
			dos.writeUTF(name);
			dos.writeUTF(notes);
			dos.writeInt(tasks.size());	//write the size of the vector to be used for deserialization
			for (int i = 0 ; i<tasks.size();i++)
			{
				((Task)tasks.elementAt(i)).serialize(dos);
			}
		}
		catch(IOException e)
		{
			System.out.println(e);
		}		
	}


	/**
	 * Write the list of given projects to record store.
	 * @param projects
	 */
    public static void saveData(Vector projects) {
		ByteArrayOutputStream bOutputStream = new ByteArrayOutputStream() ;
		DataOutputStream dataOutputStream = new DataOutputStream(bOutputStream);
		
		Tag.serializeAllTags(dataOutputStream);

		//Serialize the projects
		try {
			dataOutputStream.writeInt(projects.size());
			for(int i=0;i<projects.size();i++)
			{
				((Project)projects.elementAt(i)).serialize(dataOutputStream);
			}
			
			dataOutputStream.close();
			
			// Write to record store
			byte[] byteArray= bOutputStream.toByteArray();
			taskTracker.util.Helper.writeRS(byteArray, "data", true);
		} catch (IOException e) {
			Log.error("Error in save data", e);
		}
		
    }
	
	/**
	 * Load lists from disk (record store).
	 */
	public static Vector loadData() {
		byte[] data = taskTracker.util.Helper.readRS("data");
		Vector projectsList = new Vector();
		if (data != null) {
			ByteArrayInputStream bInputStream = new ByteArrayInputStream(data);
			DataInputStream dataInputStream = new DataInputStream(bInputStream);
			
			Tag.deserializeAllTags(dataInputStream);
			
			//deserialize the projects
			try {
				int projectsSize = dataInputStream.readInt();
				
				for(int i=0;i<projectsSize;i++)
				{
					Project project = new Project(dataInputStream);
					projectsList.addElement(project);
				}
			} catch (IOException e) {
				Log.error("Error in load data", e);
			}
		}
		return projectsList;
	}

	/**
	 * Remove all time entries associates with this project;
	 */
	public void removeTimeEntries() {
		TimeEntries.getInstance().removeTimeEntriesFor(this);
	}
}
